package com.tjdx.projectsubmission.server;

import org.springframework.stereotype.Component;
import smile.Network;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@Component
public class CollapseSet {

    // 注册许可证
    @PostConstruct
    public void initSmile() {
        new smile.License(
                "SMILE LICENSE d71328ad 873c24f0 a89d3241 " +
                        "THIS IS AN ACADEMIC LICENSE AND CAN BE USED " +
                        "SOLELY FOR ACADEMIC RESEARCH AND TEACHING, " +
                        "AS DEFINED IN THE BAYESFUSION ACADEMIC " +
                        "SOFTWARE LICENSING AGREEMENT. " +
                        "Serial #: d1g2se93o5qh3sh8l37hi05v3 " +
                        "Issued for: \u53f2 \u5929\u65d7 (1440729422@qq.com) " +
                        "Academic institution: \u540c\u6d4e\u5927\u5b66 " +
                        "Valid until: 2025-07-19 " +
                        "Issued by BayesFusion activation server",
                new byte[] {
                        17,97,-8,26,-43,14,57,119,-127,33,79,-51,9,-69,47,126,
                        15,93,81,3,79,127,-83,-72,-124,24,103,-34,-31,54,-2,-38,
                        108,19,-73,-20,-70,68,-25,-23,77,-52,-10,120,44,-41,11,-64,
                        -57,30,17,-105,19,-108,-52,-58,-70,-119,-3,-26,88,-71,100,111
                }
        );
    }


    public static Map<String,Object>  run(String x1, String x2, String x3, String x4, String x5, String x6, String x7, String x8, String x9,
                           String x10, String x11, String x12, String x13, String x14, String x15, String x16) {
        System.out.println("Starting CollapseTest...");
        Network net = new Network();

        // Load the network
        net.readFile("ComplexBayesianNetwork.xdsl");

        // 设置证据
        changeEvidenceAndUpdate(net, "X1", x1);
        changeEvidenceAndUpdate(net, "X2", x2);
        changeEvidenceAndUpdate(net, "X3", x3);
        changeEvidenceAndUpdate(net, "X4", x4);
        changeEvidenceAndUpdate(net, "X5", x5);
        changeEvidenceAndUpdate(net, "X6", x6);
        changeEvidenceAndUpdate(net, "X7", x7);
        changeEvidenceAndUpdate(net, "X8", x8);
        changeEvidenceAndUpdate(net, "X9", x9);
        changeEvidenceAndUpdate(net, "X10", x10);
        changeEvidenceAndUpdate(net, "X11", x11);
        changeEvidenceAndUpdate(net, "X12", x12);
        changeEvidenceAndUpdate(net, "X13", x13);
        changeEvidenceAndUpdate(net, "X14", x14);
        changeEvidenceAndUpdate(net, "X15", x15);
        changeEvidenceAndUpdate(net, "X16", x16);

        // 更新网络
        net.updateBeliefs();

        for (int h = net.getFirstNode(); h >= 0; h = net.getNextNode(h)) {
            String nodeId = net.getNodeId(h);
            if (net.isEvidence(h)) {
                System.out.printf("%s has evidence set (%s)\n",
                        nodeId,
                        net.getOutcomeId(h, net.getEvidence(h)));
            } else {
                double[] posteriors = net.getNodeValue(h);
                for (int i = 0; i < posteriors.length; i++) {
                    System.out.printf("P(%s=%s)=%f\n",
                            nodeId,
                            net.getOutcomeId(h, i),
                            posteriors[i]);
                }
            }
        }

        // 获取结果
        double pM1 = net.getNodeValue("T")[0]; // P(T=M1)
        double pM2 = net.getNodeValue("T")[1]; // P(T=M2)

        // 输出结果
        System.out.println("P(Concollapse=M1)=" + pM1);
        System.out.println("P(Concollapse=M2)=" + pM2);

        // 两个结果都记录以下， 用M1的概率带入这个表
        // 计算风险等级
        int riskLevel = evaluateRiskLevel(pM1);

        // 输出结果
        System.out.println("P(Concollapse=M1) = " + pM1);
        System.out.println("风险等级数字: " + riskLevel);

        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("riskLevel", riskLevel);
        dataMap.put("pM1", pM1);
        dataMap.put("pM2", pM2);
        System.out.println("InferConcollapse complete.");
        return dataMap;
    }

    private static void changeEvidenceAndUpdate(Network net, String nodeId, String outcomeId) {
        if (outcomeId != null) {
            net.setEvidence(nodeId, outcomeId);
        } else {
            net.clearEvidence(nodeId);
        }
    }

    /**
     * 根据概率值计算风险等级数字
     *
     * @param probability 概率值（例如 P(Concollapse=M1)）
     * @return 风险等级数字（1-5）
     */
    public static int evaluateRiskLevel(double probability) {
        if (probability > 0.1) {
            return 1; // 频繁的
        } else if (probability > 0.01) {
            return 2; // 可能的
        } else if (probability > 0.001) {
            return 3; // 偶尔的
        } else if (probability > 0.0001) {
            return 4; // 罕见的
        } else {
            return 5; // 不可能的
        }
    }





}
